package com.chat.api.utils.util.excel;

import com.google.common.collect.Lists;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanWriter;
import org.supercsv.prefs.CsvPreference;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 导出CSV文件
 * @author wangy
 */

public class ExportCsv<T> {

	/**
	 * 注解列表（Object[]{ ExcelField, Field/Method }）
	 */
	private List<Object[]> annotationList = Lists.newArrayList();

	/**
	 * 字段名称数组
	 */
	private String[] fieldNameList = new String[] {};

	private String[] headerList = new String[] {};

	private List<T> dataList = Lists.newArrayList();

	private boolean hasFieldHeader = false;

	/**
	  * 构造函数
	  * @param cls 实体对象，通过annotation.ExportField获取标题
	  * @param dataList 导出数据
	  * @param hasFieldHeader 是否需要字段英文名称表头
	  */
	public ExportCsv(Class<?> cls, List<T> dataList, boolean hasFieldHeader) {
		this.hasFieldHeader = hasFieldHeader;
		this.dataList = dataList;
		Field[] fs = cls.getDeclaredFields();

		for (Field f : fs) {
			ExcelField ef = f.getAnnotation(ExcelField.class);
			if (ef != null) {
				annotationList.add(new Object[] { ef, f });
			}
		}
		// Get annotation method
		Method[] ms = cls.getDeclaredMethods();
		for (Method m : ms) {
			ExcelField ef = m.getAnnotation(ExcelField.class);
			if (ef != null) {
				annotationList.add(new Object[] { ef, m });
			}
		}
		headerList = new String[annotationList.size()];
		fieldNameList = new String[annotationList.size()];
		// Field sorting
		Collections.sort(annotationList, new Comparator<Object[]>() {
			public int compare(Object[] o1, Object[] o2) {
				return new Integer(((ExcelField) o1[0]).sort()).compareTo(new Integer(((ExcelField) o2[0]).sort()));
			};
		});
		// Initialize

		for (int i = 0; i < annotationList.size(); i++) {
			Object[] os = annotationList.get(i);
			ExcelField ef = (ExcelField) os[0];
			Field f = (Field) os[1];
			headerList[i] = ef.title();
			fieldNameList[i] = f.getName();
		}

	}

	/**
	 * 输出到客户端
	 * @param fileName 输出文件名
	 */
	public void write(HttpServletResponse response, String fileName) throws IOException {
		response.reset(); // 清空输出流
		response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("utf-8"), "ISO8859_1"));
		response.setContentType("APPLICATION/OCTET-STREAM"); // 定义输出类型
		response.setCharacterEncoding("gbk");

		ICsvBeanWriter writer = null;
		writer = new CsvBeanWriter(response.getWriter(), CsvPreference.EXCEL_PREFERENCE);

		if (hasFieldHeader)
			writer.writeHeader(fieldNameList);
		writer.writeHeader(headerList);
		for (int i = 0; i < dataList.size(); i++) {
			Object values = dataList.get(i);
			writer.write(values, fieldNameList);
		}

		// 立即输出
		response.flushBuffer();
		writer.close();
	}

}
